﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CafeOnline.MvcFramework.Extensions;

namespace CafeOnline.MvcFramework.Composition {
    public class MetadataExplorer {

        private static Dictionary<Type, object> s_foundMetadata = new Dictionary<Type, object>();

        private static object s_lock = new object();

        public static IMetadata GetMetadata<IMetadata>(Type export) {
            object res = null;
            lock (s_lock) {
                if (s_foundMetadata.ContainsKey(export)) {
                    res = s_foundMetadata[export];
                } else {
                    IDictionary<string, object> props = new Dictionary<string, object>();

                    object[] attr = export.GetCustomAttributes(true);
                    foreach (Attribute a in attr) {
                        ExportAttribute expA = a as ExportAttribute;
                        if (expA != null) {
                            Type expAT = expA.GetType();
                            expAT.GetProperties().Where(t => t.CanRead).ForEach(p => {
                                if (!props.ContainsKey(p.Name)) {
                                    props.Add(p.Name, p.GetValue(expA, null));
                                }
                            });
                        }
                        ExportMetadataAttribute eM = a as ExportMetadataAttribute;
                        if (eM != null) {
                            if (!eM.IsMultiple) {
                                props.Add(eM.Name, eM.Value);
                            } else {
                                ArrayList list = new ArrayList();
                                if (props.ContainsKey(eM.Name)) {
                                    list.AddRange((ICollection)props[eM.Name]);
                                } else {
                                    props[eM.Name] = "dummy";
                                }
                                list.Add(eM.Value);
                                props[eM.Name] = list.ToArray();
                            }
                        }
                    }
                    res = AttributedModelServices.GetMetadataView<IMetadata>(props);
                    s_foundMetadata.Add(export, res);
                }
            }
            return (IMetadata)res;
        }
    }
}
